<script setup lang="ts">
import { ref, onMounted, nextTick } from 'vue'
import {
  getUserInfoListAPI,
  addUserInfoAPI,
  updateUserInfoAPI,
  getUserAllAPI,
  setUserRoleAPI,
  removeUserAPI,
  removeUserListAPI,
} from '@api/acl/user/index.ts'
import type {
  UserResponseType,
  User,
  UserAddResponseType,
  UserAllResponseType,
  roleData,
} from '@api/acl/user/type.ts'
import { ElMessage } from 'element-plus'

const pageSize = ref<number>(10)
const currentPage = ref<number>(1)
const total = ref<number>(0)
const loading = ref<boolean>(false)

// 获取列表数据
const userList = ref<User[]>([])
const getUserInfoListFn = async () => {
  loading.value = true
  const res: UserResponseType = await getUserInfoListAPI(
    currentPage.value,
    pageSize.value,
    username.value
  )
  userList.value = res.data.records
  total.value = res.data.total
  loading.value = false
}
onMounted(() => getUserInfoListFn())
// 分页器
const handleSizeChange = (e: number) => {
  pageSize.value = e
  getUserInfoListFn()
}
const handleCurrentChange = (e: number) => {
  currentPage.value = e
  getUserInfoListFn()
}

// 抽屉组件
const drawerValue = ref<boolean>(false)
const drawerTitle = ref<string>('')
const drawerData = ref<User>({})

// 点击添加按钮显示抽屉
const handleAddBtnFn = () => {
  drawerData.value = {}
  drawerValue.value = true
  drawerTitle.value = '添加用户'
  nextTick(() => {
    (formNode.value as any).clearValidate('username')
    (formNode.value as any).clearValidate('name')
    (formNode.value as any).clearValidate('password')
  })
}

// 表单校验规则
const rules = ref({
  password: [
    { required: true, trigger: ['change', 'blur'], message: '密码必填' },
    { min: 5, trigger: ['change', 'blur'], message: '密码最少5位字符' },
  ],
  name: [
    { required: true, trigger: ['change', 'blur'], message: '昵称必填' },
    { min: 5, trigger: ['change', 'blur'], message: '昵称最少5位字符' },
  ],
  username: [
    { required: true, trigger: ['change', 'blur'], message: '用户名必填' },
    { min: 5, trigger: ['change', 'blur'], message: '用户名最少5位字符' },
  ],
})

// 点击编辑按钮
const handleEditBtnFn = (row: User) => {
  drawerValue.value = true
  drawerData.value = JSON.parse(JSON.stringify(row))
  drawerTitle.value = '编辑用户'
}

// 点击确定按钮
const formNode = ref(null)
const handleConfirmFn = () => {
  (formNode.value as any).validate(async (valid: any, fields: any) => {
    if (valid) {
      if (drawerData.value.id) {
        // 编辑
        const res: UserAddResponseType = await updateUserInfoAPI(
          drawerData.value,
        )
        if (res.code !== 200) {
          ElMessage.error(res.data || res.message)
        } else {
          ElMessage.success('编辑成功')
          getUserInfoListFn()
          handleCancelFn()
        }
      } else {
        // 新增
        const res: UserAddResponseType = await addUserInfoAPI(drawerData.value)
        if (res.code !== 200) {
          ElMessage.error(res.data || res.message)
        } else {
          ElMessage.success('新增成功')
          getUserInfoListFn()
          handleCancelFn()
        }
      }
    } else {
      ElMessage.error(fields[Object.keys(fields)[0]][0].message)
    }
  })
}
// 点击取消按钮
const handleCancelFn = () => {
  drawerValue.value = false
  drawerData.value = {}
}

// 控制角色分配显隐
const drawerUser = ref<boolean>(false)

// 点击分配角色按钮
const userType = ref<User>({})
const handleUserFn = (row: User) => {
  drawerUser.value = true
  userType.value = JSON.parse(JSON.stringify(row))
  getUserAllAPI(row.id as number).then((res: UserAllResponseType) => {
    console.log(res)
    userRoles.value = res.data.allRolesList
    checkedItem.value = res.data.assignRoles

    // 如果长度一致，此事时全选状态
    if (res.data.allRolesList.length === res.data.assignRoles.length)
      checkAll.value = true

    // 有长度但不一致
    if (
      res.data.assignRoles.length &&
      res.data.assignRoles.length < res.data.allRolesList.length
    )
      isIndeterminate.value = true
  })
}

// 全选绑定
const checkAll = ref<boolean>(false)
// 全选框不确定状态设置
const isIndeterminate = ref<boolean>(false)
// 循环的复选框列表绑定
const checkedItem = ref<roleData[]>([])
const userRoles = ref<roleData[]>([])

// 点击全选框
const handleCheckAllChange = (e: boolean) => {
  isIndeterminate.value = false
  checkAll.value = e
  checkedItem.value = e ? userRoles.value : []
}
// 点击复选框组内的复选框
const handleCheckChange = (e: Array<string | number>) => {
  if (e.length === userRoles.value.length) {
    // 有选项且选项长度与原长度一致，即全选
    isIndeterminate.value = false
    checkAll.value = true
  } else if (e.length) {
    // 有选项但不全选，选择了一部分
    isIndeterminate.value = true
  } else {
    // 完全没选，为空
    isIndeterminate.value = false
    checkAll.value = false
  }
}

// 点击确定按钮
const handleUserConfirmFn = () => {
  setUserRoleAPI({
    roleIdList: checkedItem.value.map((item) => item.id) as number[],
    userId: userType.value.id as number,
  }).then(() => {
    getUserInfoListFn()
    drawerUser.value = false
    ElMessage.success('分配成功')
  })
}

// 删除业务的实现
const handleRemoveFn = (row: User) => {
  removeUserAPI(row.id as number).then(() => {
    getUserInfoListFn()
    ElMessage.success('删除成功')
  })
}

// 已被勾选的用户id
const selectIdArr = ref<(number | string)[]>([])
// 表格子复选框勾选
const selectionChangeFn = (e: any) => {
  selectIdArr.value = e.map((item: any) => item.id)
}

// 批量删除
const removeUserListFn = () => {
  removeUserListAPI(selectIdArr.value).then(() => {
    getUserInfoListFn()
    ElMessage.success('删除成功')
  })
}

// 搜索输入框
const username = ref<string>('')

// 点击搜索按钮
const handleSearchFn = () => {
  currentPage.value = 1
  getUserInfoListFn()
}
// 点击重置按钮
const handleResetFn = () => {
  currentPage.value = 1
  username.value = ''
  getUserInfoListFn()
}
</script>

<template>
  <div>
    <el-card>
      <el-form :inline="true">
        <el-form-item label="用户名：">
          <el-input v-model="username" placeholder="请输入用户名"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearchFn">搜索</el-button>
          <el-button @click="handleResetFn">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card style="margin: 20px 0">
      <el-button type="primary" @click="handleAddBtnFn">添加</el-button>
      <el-button type="danger" @click="removeUserListFn">批量删除</el-button>
      <el-table
        v-loading="loading"
        :data="userList"
        border
        style="margin: 20px 0"
        @select-all="selectionChangeFn"
        @selection-change="selectionChangeFn"
      >
        <el-table-column
          type="selection"
          align="center"
          width="100px"
        ></el-table-column>
        <el-table-column
          label="序号"
          type="index"
          align="center"
          width="100px"
        ></el-table-column>
        <el-table-column prop="id" label="id" width="100px"></el-table-column>
        <el-table-column prop="name" label="用户名字"></el-table-column>
        <el-table-column prop="username" label="用户名称"></el-table-column>
        <el-table-column prop="roleName" label="用户角色"></el-table-column>
        <el-table-column
          show-overflow-tooltip
          prop="createTime"
          label="创建时间"
        ></el-table-column>
        <el-table-column
          show-overflow-tooltip
          prop="updateTime"
          label="更新时间"
        ></el-table-column>
        <el-table-column label="操作" fixed="right" width="200px">
          <template #default="{ row }">
            <el-button size="small" icon="User" @click="handleUserFn(row)">
              分配角色
            </el-button>
            <el-button
              size="small"
              icon="Edit"
              type="primary"
              @click="handleEditBtnFn(row)"
            >
              编辑
            </el-button>
            <el-popconfirm
              title="是否确认删除该用户"
              @confirm="handleRemoveFn(row)"
            >
              <template #reference>
                <el-button type="danger" size="small" icon="Delete">
                  删除
                </el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>

      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[10, 20, 30, 40]"
        :small="true"
        :background="true"
        layout="prev, pager, next, jumper, ->, total, sizes"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </el-card>

    <el-drawer v-model="drawerValue">
      <template #header>
        {{ drawerTitle }}
      </template>
      <template #default>
        <el-form ref="formNode" :model="drawerData" :rules="rules">
          <el-form-item label="用户姓名" prop="username">
            <el-input
              v-model="drawerData.username"
              placeholder="请输入用户姓名"
            ></el-input>
          </el-form-item>
          <el-form-item label="用户昵称">
            <el-input
              v-model="drawerData.name"
              placeholder="请输入用户昵称"
            ></el-input>
          </el-form-item>
          <el-form-item v-if="!drawerData.id" label="用户密码">
            <el-input
              v-model="drawerData.password"
              placeholder="请输入用户密码"
            ></el-input>
          </el-form-item>
        </el-form>
      </template>
      <template #footer>
        <el-button type="primary" @click="handleConfirmFn">确定</el-button>
        <el-button @click="handleCancelFn">取消</el-button>
      </template>
    </el-drawer>

    <!-- 职位抽屉 -->
    <el-drawer v-model="drawerUser">
      <template #header>分配用户角色</template>
      <template #default>
        <el-form>
          <el-form-item label="用户姓名">
            <el-input v-model="userType.username" disabled></el-input>
          </el-form-item>
          <el-form-item label="职位列表">
            <el-checkbox
              v-model="checkAll"
              :indeterminate="isIndeterminate"
              @change="handleCheckAllChange"
            >
              全选
            </el-checkbox>
            <el-checkbox-group
              v-model="checkedItem"
              @change="handleCheckChange"
            >
              <el-checkbox
                v-for="item in userRoles"
                :key="item.id"
                :label="item"
              >
                {{ item.roleName }}
              </el-checkbox>
            </el-checkbox-group>
          </el-form-item>
        </el-form>
      </template>
      <template #footer>
        <el-button type="primary" @click="handleUserConfirmFn">确定</el-button>
        <el-button @click="drawerUser = false">取消</el-button>
      </template>
    </el-drawer>
  </div>
</template>

<style scoped></style>
